package ar.uba.fi.tonyvaliente.tree;

public abstract class BPlusTreeNode <K extends Comparable<K>, V> {
	protected BPlusTree<K, V> tree;
	protected BPlusTreeNodeReference<K, V> parentReference;
	protected BPlusTreeNodeReference<K, V> thisReference;
	
	protected BPlusTreeNode(BPlusTree<K, V> tree, BPlusTreeNodeReference<K, V> parentReference) {
		this.setTree(tree);
		this.setParentReference(parentReference);
	}
	
	protected abstract AddResult add(K key, V value) throws BPlusTreeException;
	protected abstract V get(K key) throws BPlusTreeException;

	protected BPlusTree<K, V> getTree() {
		return this.tree;
	}
	private void setTree(BPlusTree<K, V> tree) {
		this.tree = tree;
	}
	
	protected BPlusTreeNodeReference<K, V> getParentReference() {
		return this.parentReference;
	}
	protected void setParentReference(BPlusTreeNodeReference<K, V> parentReference) {
		this.parentReference = parentReference;
	}

	protected BPlusTreeNodeReference<K, V> getThisReference() {
		return this.thisReference;
	}
	protected void setThisReference(BPlusTreeNodeReference<K, V> thisReference) {
		this.thisReference = thisReference;
	}
	
	protected abstract boolean isInner();
	protected abstract boolean isLeaf();
	
	public class AddResult {
		private K key;
		private BPlusTreeNodeReference<K, V> leftReference;
		private BPlusTreeNodeReference<K, V> rightReference;
		
		public AddResult(K key, BPlusTreeNodeReference<K, V> leftReference, BPlusTreeNodeReference<K, V> rightReference) {
			this.key = key;
			this.leftReference = leftReference;
			this.rightReference = rightReference;
		}

		public K getKey() {
			return key;
		}

		public BPlusTreeNodeReference<K, V> getLeftReference() {
			return leftReference;
		}
		
		public BPlusTreeNodeReference<K, V> getRightReference() {
			return rightReference;
		}
	}
	
	protected abstract void validate() throws BPlusTreeException;
}
